package com.zdpx.pxframework.datapermission;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.zdpx.pxframework.datapermission.annotation.DataPermission;
import com.zdpx.pxframework.datapermission.aop.DataPermissionAnnotationAdvisor;
import com.zdpx.pxframework.datapermission.db.DataPermissionDatabaseInterceptor;
import com.zdpx.pxframework.datapermission.rule.*;
import com.zdpx.pxframework.datapermission.service.DataPermissionFrameworkService;
import com.zdpx.pxframework.datapermission.service.impl.DeptDataPermissionFrameworkServiceImpl;
import com.zdpx.pxframework.datapermission.util.MyBatisUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * 数据权限自动启动类
 *
 * @Description:
 * @Author: Cheng XiaoXiao
 * @Date: 2022/5/26 14:40
 */
@Configuration
public class DataPermissionAutoConfiguration {

    /**
     * {@link DataPermission} 注解的 Advisor 实现类
     *
     * @return Advisor
     */
    @Bean
    public DataPermissionAnnotationAdvisor dataPermissionAnnotationAdvisor() {
        return new DataPermissionAnnotationAdvisor();
    }


    /**
     * 数据权限业务处理类
     *
     * @return 数据权限业务类
     */
    @Bean
    public DataPermissionFrameworkService dataPermissionFrameworkService() {
        return new DeptDataPermissionFrameworkServiceImpl();
    }

    /**
     * 构造数据权限规则
     *
     * @param dataPermissionFrameworkService 数据权限业务逻辑
     * @param customizers                    用户自定义配置
     * @return 数据权限规则
     */
    @Bean
    public DeptDataPermissionRule dataPermissionRule(DataPermissionFrameworkService dataPermissionFrameworkService, List<DeptDataPermissionRuleCustomizer> customizers) {
        DeptDataPermissionRule rule = new DeptDataPermissionRule(dataPermissionFrameworkService);
        customizers.forEach(c -> c.customize(rule));
        return rule;
    }

    /**
     * 数据权限工厂类
     *
     * @param rules 数据权限规则
     * @return 工厂类
     */
    @Bean
    public DataPermissionRuleFactory dataPermissionRuleFactory(List<DataPermissionRule> rules) {
        return new DataPermissionRuleFactoryImpl(rules);
    }

    /**
     * 数据权限拦截器
     *
     * @param interceptor MP拦截器
     * @param rules       数据权限规则
     * @return 拦截区
     */
    @Bean
    public DataPermissionDatabaseInterceptor dataPermissionDatabaseInterceptor(MybatisPlusInterceptor interceptor,
                                                                               List<DataPermissionRule> rules) {
        // 创建 DataPermissionDatabaseInterceptor 拦截器
        DataPermissionRuleFactory ruleFactory = dataPermissionRuleFactory(rules);
        DataPermissionDatabaseInterceptor inner = new DataPermissionDatabaseInterceptor(ruleFactory);
        // 添加到 interceptor 中
        // 需要加在首个，主要是为了在分页插件前面。这个是 MyBatis Plus 的规定
        MyBatisUtils.addInterceptor(interceptor, inner, 0);
        return inner;
    }
}
